package types;

import java.util.ArrayList;

import functions.NCD;

public class DataSet {

	private ArrayList<String> dataElements;
	private Integer sizeRestricted;
	private Double sampleSize;
	private Integer numSamples;
	private Double maxDistance;
	private Integer numElements;
	private Boolean standardSelect;
	private Boolean maxDistanceSelect;
	private ArrayList<SubSet> subSets;
	private ArrayList<FinalTest> finalTests;
	
	
	// constructors
	public DataSet() {
	}
	
	public DataSet(ArrayList<String> data, Integer sizerest, Double samplesize, Integer numsamples, Boolean std, Boolean maxd, Double maxdt) {
	      this.dataElements = data;
	      this.sizeRestricted = sizerest;
	      this.sampleSize = samplesize;
	      this.numSamples = numsamples;
	      this.maxDistance = maxdt;
	      this.standardSelect = std;
	      this.maxDistanceSelect = maxd;
	      this.numElements = data.size();
	      this.subSets = new ArrayList<SubSet>();
	      this.finalTests = new ArrayList<FinalTest>();
	}
	
	
	// getters and setters
	public String getElement(Integer i){
		return this.dataElements.get(i);
	}
	
	public Integer getSizeRestricted(){
		return this.sizeRestricted;
	}
	
	public Integer getSize(){
		return this.dataElements.size();
	}
	
	public Double getSampleSize(){
		return this.sampleSize;
	}
	
	public Integer getNumSamples(){
		return this.numSamples;
	}
	
	public Double getMaxDistance(){
		return this.maxDistance;
	}
	
	public Integer getNumElements(){
		return this.numElements;
	}
	
	public void setSubSets(ArrayList<SubSet> sets){
		double dis = 0.0;
		
		for (int i=0; i<sets.size() ; i++)
			this.subSets.add(sets.get(i));
		
		if(this.isMax()){
			for(int j=0; j<subSets.size(); j++){
				for(int k=0; k<subSets.get(j).getSize(); k++){
					dis = NCD.getNCD(subSets.get(j).getElement(k), subSets.get(j).getBestMedoid());
					if(dis > this.getMaxDistance())
						subSets.get(j).deleteElement(k);
				}
			}
		}
		
		for (int i=0; i<subSets.size() ; i++)
			this.subSets.get(i).setSubSetIndexes(this);
	}
	
	public void setFinalTests(FinalTest[] tests){
		
		for(int f=0; f<tests.length; f++){
			if(tests[f]==null)
				continue;
			this.finalTests.add(tests[f]);
		}
		
	}
	
	public double[][] getDistanceMatrix() {
		int n = this.getFinalTests().size();
		double[][] result = new double[n][n];
		double dis = 0.0;
		for (int i = 0; i < n; i++) {
			for (int j = i; j < n; j++) {
				dis = NCD.getNCD(this.getFinalTests().get(i).getTest(), this.getFinalTests().get(j).getTest());
				result[i][j] = dis;
				result[j][i] = dis;
			}
		}
		return result;
	}
	


	public ArrayList<SubSet> getSubSets(){
		return this.subSets;
	}
	
	public SubSet getSubSetByIndex(int i){
		return this.subSets.get(i);
	}
	
	public ArrayList<FinalTest> getFinalTests(){
		return this.finalTests;
	}
	
	public Boolean isStd(){
		if(this.standardSelect==true)
			return true;
		else
			return false;
	}
	
	public Boolean isMax(){
		if(this.maxDistanceSelect==true)
			return true;
		else
			return false;
	}
}
